﻿#region Using

using System;
using System.Collections.Generic;
using System.Timers;

using Common.Base;

using ServerApplication.Networking;

#endregion

namespace ServerApplication.GameSession
{
    public class PausingManager
    {
        private readonly List<ServerPlayer> blackList;

        private readonly Timer maximumTimer;

        private ServerPlayer pausingPlayer;

        public PausingManager()
        {
            this.blackList = new List<ServerPlayer>();

            this.maximumTimer = new Timer(30000);
            this.maximumTimer.AutoReset = false;
            this.maximumTimer.Elapsed += this.HandleResume;

            this.pausingPlayer = ServerPlayer.EmptyPlayer;
        }

        public event EventHandler AutoResume;

        public Result Pause(ServerPlayer player)
        {
            lock (this.pausingPlayer)
            {
                if (!this.pausingPlayer.Equals(ServerPlayer.EmptyPlayer))
                {
                    return Result.Failure("Game already paused!");
                }

                if (this.blackList.Contains(player))
                {
                    return Result.Failure("You can pause a game only once!");
                }

                this.pausingPlayer = player;
                this.maximumTimer.Start();

                return Result.Success;
            }
        }

        public Result Resume(ServerPlayer player)
        {
            lock (this.pausingPlayer)
            {
                if (this.pausingPlayer.Equals(ServerPlayer.EmptyPlayer))
                {
                    return Result.Failure("Game not paused!");
                }

                if (!this.pausingPlayer.Equals(player))
                {
                    return Result.Failure("Only the pausing player can resume the game!");
                }

                this.blackList.Add(this.pausingPlayer);
                this.pausingPlayer = ServerPlayer.EmptyPlayer;
                this.maximumTimer.Stop();

                return Result.Success;
            }
        }

        private void HandleResume(object sender, ElapsedEventArgs e)
        {
            lock (this.pausingPlayer)
            {
                if (!this.pausingPlayer.Equals(ServerPlayer.EmptyPlayer))
                {
                    this.blackList.Add(this.pausingPlayer);
                    this.pausingPlayer = ServerPlayer.EmptyPlayer;
                    this.AutoResume(this, new EventArgs());
                }
            }
        }
    }
}